#include "BondDetailPrcRelevanceFilter.h"
#include "BondDetailData.h"
#include "BondDetailPrimarySimilarData.h"
#include "BondDetailPrcFilterList.h"
#include <bondlib/SSSortInfo.h>
#include <widgets/table/STable.h>
#include <uam/UserAccountManager.h>
#include <QLabel>
#include <QVBoxLayout>
#include <QTableView>
#include <QHeaderView>
#include <widgets/SCheckEx.h>
#include <widgets/table/STableColumnSet.h>
#include <QMessageBox>
#include <bitset>
#include <QPushButton>
BondDetailPrcRelevanceFilter::BondDetailPrcRelevanceFilter(QWidget* p, QSharedPointer<DetailData> data, tabFiterType fType)
	: QWidget(p), m_data(data),m_nCurrentType(fType)
{
	m_mainLayout = new QVBoxLayout;
	m_mainLayout->setContentsMargins(4, 5, 1, 1);
	if (fType != RELEVANCEFILTERISSUER)
	{
		QHBoxLayout* checkBoxLayout = new QHBoxLayout;
		checkBoxLayout->setContentsMargins(0, 2, 0, 0);
		for (int i = 0; i < m_reCheckNumb; i++)
		{
			SCheckEx* chkBox = createCheckInfo(getReComboxStr(i));
			m_nCheckVector.push_back(chkBox);
			checkBoxLayout->addWidget(m_nCheckVector[i]);
			checkBoxLayout->addSpacing(25);
			connect(m_nCheckVector[i], &SCheckEx::stateChanged,this,&BondDetailPrcRelevanceFilter::onClickCheckBox);
		}
		checkBoxLayout->addStretch(-1);
		m_mainLayout->addLayout(checkBoxLayout);
		m_mainLayout->setSpacing(2);
	}
	
	createList();
	setLayout(m_mainLayout);
	initialBroker();
}

BondDetailPrcRelevanceFilter::~BondDetailPrcRelevanceFilter()
{

}

void BondDetailPrcRelevanceFilter::refreshData()
{
	reSetPrimaryRelevanceData();
	delayReFilterData();
}

void BondDetailPrcRelevanceFilter::reSetPrimaryRelevanceData()
{
	if (m_nCurrentType != RELEVANCEFILTERISSUER && m_data->bond().IsValidBond())
	{
		if (m_nCheckVector[chk_Grade])
		{
			if (m_data->bond().IsRatingDebt())
			{
				m_nCheckVector[chk_Grade]->setEnabled(false);
				m_nCheckVector[chk_Grade]->setSelectState(Qt::Checked, true);
			}
			else
			{
				m_nCheckVector[chk_Grade]->setEnabled(true);
			}
		}
	}
	m_list->updatePrcTable();
}

void BondDetailPrcRelevanceFilter::delayReFilterData()
{
	if (m_reFltTime == nullptr)
		m_reFltTime = new QTimer(this);

	m_reFltTime->singleShot(500, [=]() {
		reFilterData();
	});
}

void BondDetailPrcRelevanceFilter::createList()
{
	if (m_nCurrentType == RELEVANCEFILTERFIRST)
		m_list = new RelevanceFirstList(this);
	else if (m_nCurrentType == RELEVANCEFILTERSECOND)
		m_list = new RelevanceSecondList(this);
	else if (m_nCurrentType == RELEVANCEFILTERISSUER)
		m_list = new SameIssurerList(this);
	m_mainLayout->addWidget(m_list);
	connect(m_list, &BondDetailPrcFilterList::bondSelected, this, &BondDetailPrcRelevanceFilter::onBondSelect);
}

void BondDetailPrcRelevanceFilter::initialBroker()
{
	const CBrokerList& brokerList = SSUserAccountManager::instance().GetReadonlyBroker();
	int nIndex = 0;
	for (CBrokerList::BrokerMap::const_iterator itor = brokerList.GetBrokerMap().begin(); itor != brokerList.GetBrokerMap().end(); ++itor)
	{
		const CBrokerUnit& stUnit = itor->second;
		if (!CBrokerList::IsValidBroker(stUnit.m_brokerID))
			continue;

		if (!stUnit.m_enableFlag_BOND && !stUnit.m_enableFlag_NCD)
			continue;

		m_mapBroker.insert(std::pair<int, CBrokerUnit>(nIndex, stUnit));

		nIndex++;
	}
}

void BondDetailPrcRelevanceFilter::reFilterData()
{
	CPrimarySimilarEx::SimilarCacheKey sck(m_data->bond().GetCombBondKey(),m_nCurrentType, buildSubType());
	std::vector<int>			vctCurrentBond;
	std::vector<BrokerKey>	vctCurrentBondValid;

	int code = CPrimarySimilarEx::GetInstance().loadSimilarEx(sck, vctCurrentBondValid, vctCurrentBond);
	
	if (code == CPrimarySimilarEx::emSuccess)
	{
			m_vctCurrentBond = vctCurrentBond;
			m_vctCurrentBondValid = vctCurrentBondValid;

		m_list->UpdateResult(m_nCurrentType, m_vctCurrentBondValid);
	}

	CPrimarySimilarEx& primaryData = CPrimarySimilarEx::GetInstance();
	if (!m_bInitConnect)
	{
		m_bInitConnect = true;
		connect(&primaryData, &CPrimarySimilarEx::notifyGetSimilarBond, this, &BondDetailPrcRelevanceFilter::onGetSimilarBond);
	}
}

int BondDetailPrcRelevanceFilter::buildSubType()
{
	std::bitset<32> bitSubType;

	if (m_nCurrentType == RELEVANCEFILTERISSUER)
	{
		bitSubType[0] = 1;
		bitSubType[1] = 1;
		bitSubType[2] = 1;
		bitSubType[3] = 1;
	}
	else if (m_nCurrentType == RELEVANCEFILTERSECOND || m_nCurrentType == RELEVANCEFILTERFIRST)
	{
		if (m_nCheckVector[chk_Grade] && m_nCheckVector[chk_Grade]->isSelected())
			bitSubType[0] = 1;
		if (m_nCheckVector[chk_SubType] && m_nCheckVector[chk_SubType]->isSelected())
			bitSubType[1] = 1;
		if (m_nCheckVector[chk_Expire] && m_nCheckVector[chk_Expire]->isSelected())
			bitSubType[2] = 1;
		if (m_nCheckVector[chk_Industry] && m_nCheckVector[chk_Industry]->isSelected())
			bitSubType[3] = 1;
	}

	return bitSubType.to_ullong();
}

QString BondDetailPrcRelevanceFilter::getReComboxStr(int i)
{
	switch (i) 
	{
		case 0: return tr("期限");
		case 1: return tr("品种");
		case 2: return tr("评级");
		case 3: return tr("行业");
		default:break;
	}
	return "";
}

SCheckEx* BondDetailPrcRelevanceFilter::createCheckInfo(QString txt)
{
	SCheckEx* chkBoxInfo = new SCheckEx(txt,this);
	chkBoxInfo->setTextBk(false); 
	if (txt == tr("期限"))
		chkBoxInfo->setSelectState(Qt::Checked, true);
	return chkBoxInfo;
}

void BondDetailPrcRelevanceFilter::onClickCheckBox()
{
	SCheckEx* chkEx = qobject_cast<SCheckEx*>(QObject::sender());

	bool bIsInt = false;
	if (m_data->bond().IsValidBond() && m_data->bond().IsRatingDebt())
		bIsInt = true;

	if (!chkEx->isSelected())
	{
		bool bHave = false;
		for (int i = 0; i < RELEVENCECHECKNUMB; i++)
		{
			if (m_nCheckVector[i]->isSelected())
			{
				if (bIsInt && i == chk_Grade)
					continue;
				bHave = true;
				break;
			}
		}
		if (!bHave)
		{
			chkEx->setSelectState(Qt::Checked, true);
			QMessageBox::information(this, "提示", tr("至少保留一个条件！"));
			return;
		}
	}
	delayReFilterData();
}

void BondDetailPrcRelevanceFilter::onGetSimilarBond(int ranKey)
{
	CPrimarySimilarEx::SimilarCacheKey sk;
	if (CPrimarySimilarEx::GetInstance().loadNotifyCombondKey(ranKey, sk))
	{
		if (sk.sCombondkey.compare(m_data->bond().GetCombBondKey()) == 0 && sk.nType == m_nCurrentType && sk.nSubType == buildSubType())
		{
			std::vector<int>			vctCurrentBond;
			std::vector<BrokerKey>	vctCurrentBondValid;
			CPrimarySimilarEx::GetInstance().loadSimilarEx(sk, vctCurrentBondValid, vctCurrentBond);

				m_vctCurrentBond = vctCurrentBond;
				m_vctCurrentBondValid = vctCurrentBondValid;

			m_list->UpdateResult(m_nCurrentType, m_vctCurrentBondValid);
		}
	}
}

void BondDetailPrcRelevanceFilter::onBondSelect(std::string bondKey)
{
	emit filterBondSelected(bondKey);
}